﻿using TemplatesDatabase;
using Vector3 = Engine.Vector3;
using Engine;
using Engine.Audio;

namespace Game
{
	public class SubsystemAudioStereo : SubsystemAudio, IUpdateable
	{
		SubsystemPlayers m_subsystemPlayers;

		public override void PlaySound(string name,float volume,float pitch,Vector3 position,float minDistance,float delay)
		{
			float num = CalculateVolume(CalculateListenerDistance(position),minDistance);
			PlaySound(name,volume * num,pitch,0f,delay,StereoConver(position));
		}
		public override void PlaySound(string name,float volume,float pitch,Vector3 position,float minDistance,bool autoDelay)
		{
			float num = CalculateVolume(CalculateListenerDistance(position),minDistance);
			PlaySound(name,volume * num,pitch,0f,autoDelay ? CalculateDelay(position) : 0f,StereoConver(position));
		}
        public override void PlayRandomSound(string directory, float volume, float pitch, Vector3 position, float minDistance, float delay)
        {
            float num = CalculateVolume(CalculateListenerDistance(position), minDistance);
            PlayRandomSound(directory, volume * num, pitch, 0f, delay,StereoConver(position));
        }
        public override void PlayRandomSound(string directory, float volume, float pitch, Vector3 position, float minDistance, bool autoDelay)
        {
            float num = CalculateVolume(CalculateListenerDistance(position), minDistance);
            PlayRandomSound(directory, volume * num, pitch, 0f, autoDelay ? CalculateDelay(position) : 0f,StereoConver(position));
        }
		public void PlayRandomSound(string directory, float volume, float pitch, float pan, float delay, Vector3 direction)
		{
			ReadOnlyList<ContentInfo> readOnlyList = ContentManager.List(directory);
			if (readOnlyList.Count > 0)
			{
				int index = m_random.Int(0, readOnlyList.Count - 1);
				PlaySound(readOnlyList[index].ContentPath, volume, pitch, pan, delay, direction);
			}
			else
			{
				Log.Warning("Sounds directory \"{0}\" not found or empty.", directory);
			}
		}
        public override void Load(ValuesDictionary valuesDictionary)
		{
			m_subsystemTime = base.Project.FindSubsystem<SubsystemTime>(throwOnError: true);
			m_subsystemViews = base.Project.FindSubsystem<SubsystemGameWidgets>(throwOnError: true);
			m_subsystemPlayers = Project?.FindSubsystem<SubsystemPlayers>(true);
		}

		/// <summary>
		/// 通过玩家和音频源的位置计算出带方向的相对位置
		/// </summary>
		/// <param name="position">音频源位置</param>
		/// <returns></returns>
		public Vector3 StereoConver(Vector3 position)
		{
			var player = m_subsystemPlayers.FindNearestPlayer(position).ComponentBody;
			return Vector3.Transform(position-player.Matrix.Translation,Matrix.Invert(player.Matrix.OrientationMatrix));
			//return (position - player.Matrix.Translation) * player.Matrix.OrientationMatrix.Right;
				/*new Vector3(
			(position.X - player.Matrix.M41) * player.Matrix.M11 * 0.5f,
			0,
			(position.Z - player.Matrix.M43) * player.Matrix.M13 * 0.5f);*/
		}
	}
}
